<script setup>
import { ref, onMounted } from "vue";
import { VueFlow, useVueFlow, SelectionMode } from "@vue-flow/core";
import { Controls, ControlButton } from "@vue-flow/controls";
import { ElMessage } from "element-plus";
import DropzoneBackground from "./DropzoneBackground.vue";
import Sidebar from "./Sidebar.vue";
import useDragAndDrop from "./useDnD";
import { assignProcessesToRoute, getRouteProcesses } from "@/api/modules/route";
import "./main.css";

const nodes = ref([]);
const edges = ref([]);
const visible = ref(false);
const routeData = ref({});

// VueFlow 相关
const { onConnect, addEdges, getNodes, removeNodes, updateNode, getSelectedNodes, fitView, toObject } = useVueFlow();

// 控制按钮功能
const dark = ref(false);

// 重置视图变换
const resetTransform = () => {
  fitView();
  ElMessage.success("视图已重置");
};

// 随机更新节点位置
const updatePos = () => {
  nodes.value.forEach(node => {
    if (node.type !== "input" && node.type !== "output") {
      const newX = Math.random() * 500 + 50;
      const newY = Math.random() * 300 + 50;
      updateNode(node.id, { position: { x: newX, y: newY } });
    }
  });
  ElMessage.success("节点位置已随机更新");
};

// 切换暗黑模式
const toggleDarkMode = () => {
  dark.value = !dark.value;

  // 使用CSS类来管理主题，更加优雅
  const dialogElement = document.querySelector(".el-dialog");

  if (dark.value) {
    dialogElement?.classList.add("dark-theme");
    dialogElement?.classList.remove("light-theme");
  } else {
    dialogElement?.classList.add("light-theme");
    dialogElement?.classList.remove("dark-theme");
  }

  ElMessage.success(dark.value ? "已切换到暗黑模式" : "已切换到明亮模式");
};

// 输出对象到控制台
const logToObject = () => {
  const flowData = toObject();
  console.log("Flow Data:", flowData);
  ElMessage.success("流程数据已输出到控制台");
};

// 拖拽相关状态 - 传入 VueFlow 实例
const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();

// 选中的节点
const selectedNodes = ref([]);

onConnect(addEdges);

// 监听节点选择变化
const handleSelectionChange = ({ nodes: selectedNodesList }) => {
  selectedNodes.value = selectedNodesList;
  console.log("选中的节点:", selectedNodesList);
};

// 处理节点点击
const handleNodeClick = ({ event, node }) => {
  console.log("节点被点击:", node);

  // 检查是否按住了 Ctrl 或 Cmd 键进行多选
  if (event.ctrlKey || event.metaKey) {
    // 多选模式
    const currentSelected = [...selectedNodes.value];
    const nodeIndex = currentSelected.findIndex(n => n.id === node.id);

    if (nodeIndex >= 0) {
      // 如果节点已选中，则取消选中
      currentSelected.splice(nodeIndex, 1);
    } else {
      // 如果节点未选中，则添加到选中列表
      currentSelected.push(node);
    }

    // 更新节点的选中状态和样式
    nodes.value.forEach(n => {
      const isSelected = currentSelected.some(selected => selected.id === n.id);
      updateNode(n.id, {
        selected: isSelected,
        style: isSelected
          ? {
              border: "2px solid #1890ff",
              backgroundColor: "#e6f7ff",
              boxShadow: "0 0 0 2px rgba(24, 144, 255, 0.2)"
            }
          : {
              border: "1px solid #d9d9d9",
              backgroundColor: "white",
              boxShadow: "none"
            }
      });
    });

    selectedNodes.value = currentSelected;
  } else {
    // 单选模式
    nodes.value.forEach(n => {
      const isSelected = n.id === node.id;
      updateNode(n.id, {
        selected: isSelected,
        style: isSelected
          ? {
              border: "2px solid #1890ff",
              backgroundColor: "#e6f7ff",
              boxShadow: "0 0 0 2px rgba(24, 144, 255, 0.2)"
            }
          : {
              border: "1px solid #d9d9d9",
              backgroundColor: "white",
              boxShadow: "none"
            }
      });
    });
    selectedNodes.value = [node];
  }
};

// 处理节点右键菜单
const handleNodeContextMenu = ({ event, node }) => {
  // 检查 event 是否存在 preventDefault 方法
  if (event && typeof event.preventDefault === "function") {
    event.preventDefault();
  }

  // 开始和结束节点不显示右键菜单
  if (node.id === "start" || node.id === "end") {
    return;
  }

  // 获取鼠标位置，优先使用原始事件的位置
  const clientX = event?.clientX || event?.pageX || 0;
  const clientY = event?.clientY || event?.pageY || 0;

  // 创建右键菜单
  const contextMenu = document.createElement("div");
  contextMenu.className = "context-menu";
  contextMenu.style.cssText = `
    position: fixed;
    top: ${clientY}px;
    left: ${clientX}px;
    background: white;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    z-index: 9999;
    padding: 4px 0;
    min-width: 120px;
  `;

  const deleteItem = document.createElement("div");
  deleteItem.className = "context-menu-item";
  deleteItem.textContent = "删除节点";
  deleteItem.style.cssText = `
    padding: 8px 16px;
    cursor: pointer;
    color: #ff4d4f;
    font-size: 14px;
  `;

  deleteItem.addEventListener("mouseenter", () => {
    deleteItem.style.backgroundColor = "#f5f5f5";
  });

  deleteItem.addEventListener("mouseleave", () => {
    deleteItem.style.backgroundColor = "transparent";
  });

  deleteItem.addEventListener("click", () => {
    handleRemoveNode(node.id);
    if (document.body.contains(contextMenu)) {
      document.body.removeChild(contextMenu);
    }
  });

  contextMenu.appendChild(deleteItem);
  document.body.appendChild(contextMenu);

  // 点击其他地方关闭菜单
  const closeMenu = e => {
    if (!contextMenu.contains(e.target) && document.body.contains(contextMenu)) {
      document.body.removeChild(contextMenu);
      document.removeEventListener("click", closeMenu);
    }
  };

  setTimeout(() => {
    document.addEventListener("click", closeMenu);
  }, 0);
};

// 移除节点
const handleRemoveNode = nodeId => {
  // 防止删除开始和结束节点
  if (nodeId === "start" || nodeId === "end") {
    ElMessage.warning("开始和结束节点不能删除");
    return;
  }

  removeNodes([nodeId]);
  ElMessage.success("节点已删除");
};

// 对齐功能
const alignNodes = type => {
  const selected = getSelectedNodes.value;
  if (selected.length < 2) {
    ElMessage.warning("请至少选择两个节点进行对齐");
    return;
  }

  let referenceValue;

  switch (type) {
    case "left":
      // 左对齐：以最左边的节点为基准
      referenceValue = Math.min(...selected.map(node => node.position.x));
      selected.forEach(node => {
        updateNode(node.id, { position: { x: referenceValue, y: node.position.y } });
      });
      break;

    case "right":
      // 右对齐：以最右边的节点为基准
      referenceValue = Math.max(...selected.map(node => node.position.x + (node.dimensions?.width || 150)));
      selected.forEach(node => {
        const nodeWidth = node.dimensions?.width || 150;
        updateNode(node.id, { position: { x: referenceValue - nodeWidth, y: node.position.y } });
      });
      break;

    case "top":
      // 顶部对齐：以最上面的节点为基准
      referenceValue = Math.min(...selected.map(node => node.position.y));
      selected.forEach(node => {
        updateNode(node.id, { position: { x: node.position.x, y: referenceValue } });
      });
      break;

    case "bottom":
      // 底部对齐：以最下面的节点为基准
      referenceValue = Math.max(...selected.map(node => node.position.y + (node.dimensions?.height || 40)));
      selected.forEach(node => {
        const nodeHeight = node.dimensions?.height || 40;
        updateNode(node.id, { position: { x: node.position.x, y: referenceValue - nodeHeight } });
      });
      break;

    case "center-horizontal":
      // 水平居中对齐
      const centerY =
        selected.reduce((sum, node) => sum + node.position.y + (node.dimensions?.height || 40) / 2, 0) / selected.length;
      selected.forEach(node => {
        const nodeHeight = node.dimensions?.height || 40;
        updateNode(node.id, { position: { x: node.position.x, y: centerY - nodeHeight / 2 } });
      });
      break;

    case "center-vertical":
      // 垂直居中对齐
      const centerX =
        selected.reduce((sum, node) => sum + node.position.x + (node.dimensions?.width || 150) / 2, 0) / selected.length;
      selected.forEach(node => {
        const nodeWidth = node.dimensions?.width || 150;
        updateNode(node.id, { position: { x: centerX - nodeWidth / 2, y: node.position.y } });
      });
      break;

    case "distribute-horizontal":
      // 水平分布
      if (selected.length < 3) {
        ElMessage.warning("水平分布需要至少3个节点");
        return;
      }
      const sortedByX = [...selected].sort((a, b) => a.position.x - b.position.x);
      const leftMost = sortedByX[0].position.x;
      const rightMost = sortedByX[sortedByX.length - 1].position.x + (sortedByX[sortedByX.length - 1].dimensions?.width || 150);
      const totalWidth = rightMost - leftMost;
      const spacing = totalWidth / (selected.length - 1);

      sortedByX.forEach((node, index) => {
        if (index > 0 && index < sortedByX.length - 1) {
          updateNode(node.id, { position: { x: leftMost + spacing * index, y: node.position.y } });
        }
      });
      break;

    case "distribute-vertical":
      // 垂直分布
      if (selected.length < 3) {
        ElMessage.warning("垂直分布需要至少3个节点");
        return;
      }
      const sortedByY = [...selected].sort((a, b) => a.position.y - b.position.y);
      const topMost = sortedByY[0].position.y;
      const bottomMost = sortedByY[sortedByY.length - 1].position.y + (sortedByY[sortedByY.length - 1].dimensions?.height || 40);
      const totalHeight = bottomMost - topMost;
      const vSpacing = totalHeight / (selected.length - 1);

      sortedByY.forEach((node, index) => {
        if (index > 0 && index < sortedByY.length - 1) {
          updateNode(node.id, { position: { x: node.position.x, y: topMost + vSpacing * index } });
        }
      });
      break;
  }

  ElMessage.success(
    `节点${
      type === "center-horizontal"
        ? "水平居中"
        : type === "center-vertical"
        ? "垂直居中"
        : type === "distribute-horizontal"
        ? "水平分布"
        : type === "distribute-vertical"
        ? "垂直分布"
        : type
    }对齐完成`
  );
};

// 加载工艺路线的工序节点
const loadRouteProcesses = async routeId => {
  try {
    const response = await getRouteProcesses(routeId);

    // 创建开始节点
    const startNode = {
      id: "start",
      type: "input",
      position: { x: 50, y: 150 },
      data: {
        label: "开始"
      },
      style: {
        backgroundColor: "#67c23a",
        color: "white",
        border: "2px solid #67c23a",
        borderRadius: "50%",
        width: "80px",
        height: "80px",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        fontWeight: "bold"
      }
    };

    let allNodes = [startNode];
    let allEdges = [];

    if (response.data && response.data.length > 0) {
      // 按stepOrder排序工序
      const sortedProcesses = response.data.sort((a, b) => a.stepOrder - b.stepOrder);

      // 将工序转换为节点
      const processNodes = sortedProcesses.map((process, index) => ({
        id: `process-${process.processId}`,
        type: "default",
        position: {
          x: 250 + index * 200, // 水平排列，每个节点间距200px
          y: 150 // 与开始节点同一水平线
        },
        data: {
          processId: process.processId,
          label: `${process.processCode}\n${process.processName}`,
          stepOrder: process.stepOrder,
          remark: process.remark
        },
        style: {
          border: "1px solid #409eff",
          backgroundColor: "#ecf5ff",
          borderRadius: "6px",
          padding: "8px",
          minWidth: "150px",
          textAlign: "center",
          fontSize: "12px"
        }
      }));

      // 创建结束节点
      const endNode = {
        id: "end",
        type: "output",
        position: {
          x: 250 + processNodes.length * 200, // 在最后一个工序节点后面
          y: 150
        },
        data: {
          label: "结束"
        },
        style: {
          backgroundColor: "#f56c6c",
          color: "white",
          border: "2px solid #f56c6c",
          borderRadius: "50%",
          width: "80px",
          height: "80px",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          fontWeight: "bold"
        }
      };

      // 合并所有节点
      allNodes = [startNode, ...processNodes, endNode];

      // 创建连接线
      // 开始节点连接到第一个工序
      if (processNodes.length > 0) {
        allEdges.push({
          id: "start-to-first",
          source: "start",
          target: processNodes[0].id,
          type: "smoothstep",
          style: { stroke: "#409eff", strokeWidth: 2 },
          markerEnd: {
            type: "arrowclosed",
            color: "#409eff"
          }
        });

        // 工序之间的连接
        for (let i = 0; i < processNodes.length - 1; i++) {
          allEdges.push({
            id: `${processNodes[i].id}-to-${processNodes[i + 1].id}`,
            source: processNodes[i].id,
            target: processNodes[i + 1].id,
            type: "smoothstep",
            style: { stroke: "#409eff", strokeWidth: 2 },
            markerEnd: {
              type: "arrowclosed",
              color: "#409eff"
            }
          });
        }

        // 最后一个工序连接到结束节点
        allEdges.push({
          id: "last-to-end",
          source: processNodes[processNodes.length - 1].id,
          target: "end",
          type: "smoothstep",
          style: { stroke: "#409eff", strokeWidth: 2 },
          markerEnd: {
            type: "arrowclosed",
            color: "#409eff"
          }
        });
      } else {
        // 如果没有工序，直接连接开始和结束
        const endNodeNoProcess = {
          ...endNode,
          position: { x: 350, y: 150 }
        };
        allNodes = [startNode, endNodeNoProcess];
        allEdges.push({
          id: "start-to-end",
          source: "start",
          target: "end",
          type: "smoothstep",
          style: { stroke: "#909399", strokeWidth: 2, strokeDasharray: "5,5" },
          markerEnd: {
            type: "arrowclosed",
            color: "#909399"
          }
        });
      }

      console.log("已加载工序节点：", processNodes);
      ElMessage.success(`已加载 ${processNodes.length} 个工序节点，并自动连接流程`);
    } else {
      // 没有工序时，只显示开始和结束节点，不连接
      const endNodeEmpty = {
        id: "end",
        type: "output",
        position: { x: 350, y: 150 },
        data: { label: "结束" },
        style: {
          backgroundColor: "#f56c6c",
          color: "white",
          border: "2px solid #f56c6c",
          borderRadius: "50%",
          width: "80px",
          height: "80px",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          fontWeight: "bold"
        }
      };

      allNodes = [startNode, endNodeEmpty];
      allEdges = []; // 没有工序时不创建任何连接线

      console.log("该工艺路线暂无分配工序，显示空流程");
      ElMessage.info("该工艺路线暂无分配工序");
    }

    // 设置节点和边
    nodes.value = allNodes;
    edges.value = allEdges;

    // 延迟一下再调整视图，确保节点已渲染
    setTimeout(() => {
      fitView({ padding: 0.1 });
    }, 100);
  } catch (error) {
    console.error("加载工序节点失败:", error);
    ElMessage.error("加载工序节点失败：" + (error.message || "未知错误"));

    // 出错时也显示基本的开始结束节点
    nodes.value = [
      {
        id: "start",
        type: "input",
        position: { x: 50, y: 150 },
        data: { label: "开始" },
        style: {
          backgroundColor: "#67c23a",
          color: "white",
          border: "2px solid #67c23a",
          borderRadius: "50%",
          width: "80px",
          height: "80px",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          fontWeight: "bold"
        }
      },
      {
        id: "end",
        type: "output",
        position: { x: 350, y: 150 },
        data: { label: "结束" },
        style: {
          backgroundColor: "#f56c6c",
          color: "white",
          border: "2px solid #f56c6c",
          borderRadius: "50%",
          width: "80px",
          height: "80px",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          fontWeight: "bold"
        }
      }
    ];
    edges.value = [];
  }
};

// 暴露打开方法
const open = async params => {
  visible.value = true;
  routeData.value = params.row || {};
  // 清空之前的节点和边
  nodes.value = [];
  edges.value = [];

  console.log("打开流程设计器，路线数据：", routeData.value);

  // 如果有工艺路线ID，则加载已分配的工序
  if (routeData.value && routeData.value.id) {
    await loadRouteProcesses(routeData.value.id);
  }
};

// 关闭方法
const close = () => {
  visible.value = false;
  routeData.value = {};
};

// 检查流程连线是否完整
const validateFlowConnections = () => {
  const allNodes = nodes.value;
  const allEdges = edges.value;

  // 提取所有节点ID
  const nodeIds = allNodes.map(node => node.id);

  // 如果只有开始和结束节点，不需要检查连线
  if (nodeIds.length <= 2) {
    return { valid: true, message: "" };
  }

  // 检查开始节点是否有出边
  const startNode = allNodes.find(node => node.id === "start");
  if (!startNode) {
    return { valid: false, message: "缺少开始节点" };
  }

  const startOutEdges = allEdges.filter(edge => edge.source === "start");
  if (startOutEdges.length === 0) {
    return { valid: false, message: "开始节点必须连接到下一个节点" };
  }

  // 检查结束节点是否有入边
  const endNode = allNodes.find(node => node.id === "end");
  if (!endNode) {
    return { valid: false, message: "缺少结束节点" };
  }

  const endInEdges = allEdges.filter(edge => edge.target === "end");
  if (endInEdges.length === 0) {
    return { valid: false, message: "结束节点必须有前置节点连接" };
  }

  // 检查所有工序节点是否都在流程链中
  const processNodes = allNodes.filter(node => node.type === "default" && node.data && node.data.processId);

  for (const processNode of processNodes) {
    // 检查每个工序节点是否有入边（除了第一个可能直接连开始节点）
    const inEdges = allEdges.filter(edge => edge.target === processNode.id);
    // 检查每个工序节点是否有出边（除了最后一个可能直接连结束节点）
    const outEdges = allEdges.filter(edge => edge.source === processNode.id);

    if (inEdges.length === 0 && outEdges.length === 0) {
      return { valid: false, message: `工序节点 "${processNode.data.label}" 没有连接到流程中` };
    }

    if (inEdges.length === 0) {
      // 如果没有入边，必须是开始节点直接连接的
      const startToThis = allEdges.find(edge => edge.source === "start" && edge.target === processNode.id);
      if (!startToThis) {
        return { valid: false, message: `工序节点 "${processNode.data.label}" 没有前置连接` };
      }
    }

    if (outEdges.length === 0) {
      // 如果没有出边，必须直接连接到结束节点
      const thisToEnd = allEdges.find(edge => edge.source === processNode.id && edge.target === "end");
      if (!thisToEnd) {
        return { valid: false, message: `工序节点 "${processNode.data.label}" 没有后续连接` };
      }
    }
  }

  // 检查是否形成完整的从开始到结束的路径
  const visited = new Set();
  const queue = ["start"];
  visited.add("start");

  while (queue.length > 0) {
    const currentNode = queue.shift();
    const outEdges = allEdges.filter(edge => edge.source === currentNode);

    for (const edge of outEdges) {
      if (!visited.has(edge.target)) {
        visited.add(edge.target);
        queue.push(edge.target);
      }
    }
  }

  // 检查是否能到达结束节点
  if (!visited.has("end")) {
    return { valid: false, message: "流程中存在断开的连接，无法从开始节点到达结束节点" };
  }

  // 检查是否所有节点都在路径中
  for (const node of allNodes) {
    if (!visited.has(node.id)) {
      return { valid: false, message: `节点 "${node.data?.label || node.id}" 不在主流程路径中` };
    }
  }

  return { valid: true, message: "流程连接检查通过" };
};

// 保存方法
const handleSave = async () => {
  try {
    // 检查是否有工艺路线数据
    if (!routeData.value || !routeData.value.id) {
      ElMessage.error("工艺路线数据不完整，无法保存");
      return;
    }

    console.log("nodes", nodes);
    // 提取画布上的工序节点（排除开始和结束节点）
    const processNodes = nodes.value.filter(node => node.type === "default" && node.data && node.data.processId);

    console.log("提取的工序节点：", processNodes);

    // 如果没有工序节点，提示用户
    if (processNodes.length === 0) {
      ElMessage.warning("请先拖拽工序到画布上再保存");
      return;
    }

    // 检查流程连线是否完整
    const connectionCheck = validateFlowConnections();
    if (!connectionCheck.valid) {
      ElMessage.error(`流程连接不完整：${connectionCheck.message}`);
      return;
    }

    // 提取工序ID列表（全局拦截器会自动处理长整型精度问题）
    const processIds = processNodes.map(node => node.data.processId);

    console.log("准备保存的工序ID列表：", processIds);
    console.log("工艺路线ID：", routeData.value.id);

    // 调用API保存工序分配
    const params = {
      processIds: processIds
    };

    // 直接使用字符串形式的ID，避免精度丢失
    const routeId = routeData.value.id;
    await assignProcessesToRoute(routeId, params);

    ElMessage.success("工艺流程保存成功！");
    console.log("工艺流程保存成功");

    // 保存成功后关闭对话框
    close();
  } catch (error) {
    console.error("保存工艺流程失败:", error);
    ElMessage.error("保存工艺流程失败：" + (error.message || "未知错误"));
  }
};

// 暴露方法给父组件使用
defineExpose({
  open,
  close
});
</script>

<template>
  <el-dialog v-model="visible" title="工艺流程设计" width="1200px" :before-close="close" top="5vh">
    <div class="dnd-flow">
      <div class="vue-flow-container">
        <!-- 对齐工具栏 -->
        <div class="align-toolbar" v-show="selectedNodes.length >= 2">
          <div class="toolbar-title">对齐工具 (已选择 {{ selectedNodes.length }} 个节点)</div>
          <div class="toolbar-buttons">
            <el-button-group>
              <el-button size="small" @click="alignNodes('left')" title="左对齐">
                <i class="el-icon-align-left">⫷</i>
              </el-button>
              <el-button size="small" @click="alignNodes('center-vertical')" title="垂直居中">
                <i class="el-icon-align-center">⫸</i>
              </el-button>
              <el-button size="small" @click="alignNodes('right')" title="右对齐">
                <i class="el-icon-align-right">⫹</i>
              </el-button>
            </el-button-group>

            <el-button-group>
              <el-button size="small" @click="alignNodes('top')" title="顶部对齐">
                <i class="el-icon-align-top">⫯</i>
              </el-button>
              <el-button size="small" @click="alignNodes('center-horizontal')" title="水平居中">
                <i class="el-icon-align-middle">⫰</i>
              </el-button>
              <el-button size="small" @click="alignNodes('bottom')" title="底部对齐">
                <i class="el-icon-align-bottom">⫱</i>
              </el-button>
            </el-button-group>

            <el-button-group v-show="selectedNodes.length >= 3">
              <el-button size="small" @click="alignNodes('distribute-horizontal')" title="水平分布">
                <i class="el-icon-distribute-horizontal">⟷</i>
              </el-button>
              <el-button size="small" @click="alignNodes('distribute-vertical')" title="垂直分布">
                <i class="el-icon-distribute-vertical">⟵</i>
              </el-button>
            </el-button-group>
          </div>
        </div>

        <VueFlow
          v-model:nodes="nodes"
          v-model:edges="edges"
          @dragover="onDragOver"
          @dragleave="onDragLeave"
          @drop="onDrop"
          @node-click="handleNodeClick"
          @node-context-menu="handleNodeContextMenu"
          @selection-change="handleSelectionChange"
          :selection-mode="SelectionMode.Partial"
          :multi-selection-key-code="null"
          :delete-key-code="'Delete'"
          :pan-on-drag="[1, 2]"
          :nodes-draggable="true"
          :nodes-connectable="true"
          :elements-selectable="true"
        >
          <DropzoneBackground
            :style="{
              backgroundColor: isDragOver ? '#e7f3ff' : 'transparent',
              transition: 'background-color 0.2s ease'
            }"
          >
            <p v-if="isDragOver">拖拽到这里</p>
          </DropzoneBackground>

          <Controls position="top-left">
            <ControlButton title="重置视图" @click="resetTransform"> 🔄 </ControlButton>

            <ControlButton title="随机排列节点" @click="updatePos"> 🎲 </ControlButton>

            <ControlButton title="切换主题" @click="toggleDarkMode">
              {{ dark ? "☀️" : "🌙" }}
            </ControlButton>

            <ControlButton title="导出流程数据" @click="logToObject"> 📋 </ControlButton>
          </Controls>
        </VueFlow>
      </div>

      <Sidebar />
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="close">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style scoped>
.dialog-footer {
  text-align: right;
}

.dnd-flow {
  height: 600px;
  display: flex;
  flex-direction: row;
}

.vue-flow-container {
  flex: 1;
  height: 100%;
}

.dnd-flow .vue-flow {
  flex: 1;
  height: 100%;
}

/* 对齐工具栏样式 */
.align-toolbar {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 8px 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-title {
  font-size: 12px;
  color: #606266;
  white-space: nowrap;
}

.toolbar-buttons {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-buttons .el-button-group {
  margin: 0;
}

.toolbar-buttons .el-button {
  padding: 4px 8px;
  font-size: 16px;
  min-width: 28px;
  height: 28px;
}

.toolbar-buttons .el-button i {
  font-style: normal;
  font-weight: bold;
}

/* 主题切换样式 */
:deep(.el-dialog.dark-theme) {
  background-color: #1a1a1a !important;
  color: #ffffff !important;
  border-color: #404040 !important;
}

:deep(.el-dialog.dark-theme .el-dialog__header) {
  background-color: #2d2d2d !important;
  color: #ffffff !important;
  border-bottom: 1px solid #404040 !important;
}

:deep(.el-dialog.dark-theme .el-dialog__body) {
  background-color: #1a1a1a !important;
  color: #ffffff !important;
}

:deep(.el-dialog.dark-theme .el-dialog__footer) {
  background-color: #2d2d2d !important;
  border-top: 1px solid #404040 !important;
}

/* 暗黑模式下的工具栏 */
.dark-theme .align-toolbar {
  background-color: #404040 !important;
  border-color: #606060 !important;
  color: #ffffff !important;
}

.dark-theme .toolbar-title {
  color: #ffffff !important;
}

/* 暗黑模式下的流程容器 */
.dark-theme .vue-flow-container {
  background-color: #2d2d2d !important;
}

/* 暗黑模式下的侧边栏 */
.dark-theme aside {
  background-color: #1e3a8a !important;
  color: #ffffff !important;
}

/* 暗黑模式下的右键菜单 */
.dark-theme .context-menu {
  background-color: #404040 !important;
  border-color: #606060 !important;
  color: #ffffff !important;
}

.dark-theme .context-menu-item:hover {
  background-color: #505050 !important;
}

/* 明亮模式样式 */
:deep(.el-dialog.light-theme) {
  background-color: #ffffff !important;
  color: #000000 !important;
  border-color: #e4e7ed !important;
}

:deep(.el-dialog.light-theme .el-dialog__header) {
  background-color: #ffffff !important;
  color: #000000 !important;
  border-bottom: 1px solid #e4e7ed !important;
}

:deep(.el-dialog.light-theme .el-dialog__body) {
  background-color: #ffffff !important;
  color: #000000 !important;
}

:deep(.el-dialog.light-theme .el-dialog__footer) {
  background-color: #ffffff !important;
  border-top: 1px solid #e4e7ed !important;
}

/* 明亮模式下的工具栏 */
.light-theme .align-toolbar {
  background-color: #ffffff !important;
  border-color: #e4e7ed !important;
  color: #606266 !important;
}

.light-theme .toolbar-title {
  color: #606266 !important;
}

/* 明亮模式下的流程容器 */
.light-theme .vue-flow-container {
  background-color: #ffffff !important;
}

/* 明亮模式下的侧边栏 */
.light-theme aside {
  background-color: #10b981bf !important;
  color: #ffffff !important;
}
</style>

